using DataAnalyticsTools.Core;
using DataAnalyticsTools.Models;
using GrapeCity.Forguncy.Commands;
using GrapeCity.Forguncy.Log;
using GrapeCity.Forguncy.Plugin;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Threading.Tasks;

namespace DataAnalyticsTools
{
    [Icon("pack://application:,,,/DataAnalyticsTools;component/Resources/Icon.png")]
    [Designer("DataAnalyticsTools.Designer.DataAnalyticsToolsServerCommandDesigner, DataAnalyticsTools")]
    [Category("数据分析")]
    [OrderWeight(210)]
    public class ClusterByHierarchical : Command, ICommandExecutableInServerSideAsync, IServerCommandParamGenerator
    {
        [FormulaProperty]
        [DisplayName("特征矩阵")]
        [Description("float[][]二维数组，外层为样本，内层为该样本的各维度特征。")]
        public object featuresExpr { get; set; }

        [FormulaProperty]
        [DisplayName("要形成的簇数量")]
        public object clusterCountExpr { get; set; } = 5;

        [DisplayName("链接方法")]
        public LinkageMethod LinkageMethod { get; set; } 


        [ResultToProperty]
        [DisplayName("保存聚类后的簇到变量")]
        [Description("每个簇的ID为ClusterId属性，样本ID数组为SampleIndices属性")]
        public string ResultTo { get; set; } = "聚类后的簇";


        [ResultToProperty]
        [DisplayName("保存原始结果到变量")]
        public string ResultTo2 { get; set; } = "原始结果";

        public async Task<ExecuteResult> ExecuteAsync(IServerCommandExecuteContext dataContext)
        {
            var features = GeneralConvertors.ConvertToFloatMatrix(await dataContext.EvaluateFormulaAsync(featuresExpr));

            var clusterCount = int.Parse((await dataContext.EvaluateFormulaAsync(clusterCountExpr))?.ToString() ?? "5");

            // 执行计算
            var result = ClusteringAnalyzer.HierarchicalClustering(features, clusterCount, LinkageMethod);

            dataContext.Parameters[ResultTo] = result.ToClusterList(features);
            dataContext.Parameters[ResultTo2] = result;

            return new ExecuteResult();
        }

        public override string ToString()
        {
            if (featuresExpr == null)
            {
                return "聚类（层次化法）";
            }
            else
            {
                return "聚类（层次化法）：" + ResultTo;
            }
        }

        public override CommandScope GetCommandScope()
        {
            return CommandScope.ExecutableInServer;
        }

        public IEnumerable<GenerateParam> GetGenerateParams()
        {
            List<GenerateParam> result = [];

            result.Add(new GenerateListParam()
            {
                ParamName = this.ResultTo,
                Description = "聚类后的簇",
                ParamScope = CommandScope.All,
                ItemProperties = new List<string>() {
                    "ClusterId",
                    "ClusteringQuality",
                    "Centroid",
                    "SampleIndices",
                    "Samples",
                    "SilhouetteScores",
                    "SampleCount",
                    "AverageSilhouetteScore",
                    "MaxDistanceToCentroid",
                    "AverageDistanceToCentroid"
                }
            });

            result.Add(new GenerateObjectParam()
            {
                ParamName = this.ResultTo2,
                Description = "聚类的原始结果",
                ParamScope = CommandScope.All,
                SubPropertiesDescription = new Dictionary<string, string>() {
                    { "Labels","标签的数组"},
                    { "Centroids","聚类中心的数组"},
                    { "SilhouetteScores","轮廓系数的数组"},
                    { "AverageSilhouetteScore","平均轮廓系数（聚类质量）"},
                    { "ConvergenceReached","是否收敛（聚类质量）"},
                    { "MergeHistory","合并历史"}
                }
            });

            return result;
        }
    }
}
